<template>
  <div class="knowledge-file-list">
    <!-- 搜索栏 -->
    <div class="search-bar">
      <el-input
        v-model="searchKeyword"
        placeholder="搜索文件..."
        clearable
        @input="handleSearch"
        @clear="handleSearch"
        class="search-input"
      >
        <template #prefix>
          <el-icon><Search /></el-icon>
        </template>
      </el-input>
      <el-select
        v-model="fileTypeFilter"
        placeholder="文件类型"
        clearable
        style="width: 150px"
        @change="handleFilterChange"
      >
        <el-option label="全部" value="" />
        <el-option label="文档" value="document" />
        <el-option label="图片" value="image" />
        <el-option label="视频" value="video" />
        <el-option label="音频" value="audio" />
        <el-option label="其他" value="other" />
      </el-select>
      <div class="view-toggle">
        <el-radio-group v-model="viewMode" size="default" class="view-mode-switcher">
          <el-radio-button label="grid">
            <el-icon><Grid /></el-icon>
            <span class="view-label">网格</span>
          </el-radio-button>
          <el-radio-button label="list">
            <el-icon><List /></el-icon>
            <span class="view-label">列表</span>
          </el-radio-button>
        </el-radio-group>
      </div>
    </div>

    <!-- 批量操作栏 -->
    <div v-if="selectedFiles.length > 0" class="batch-actions-bar">
      <div class="batch-info">
        <el-icon><Select /></el-icon>
        <span>已选择 <strong>{{ selectedFiles.length }}</strong> 个文件</span>
        <el-button text size="small" @click="clearSelection">取消选择</el-button>
      </div>
      <div class="batch-buttons">
        <el-button
          type="danger"
          size="small"
          @click="handleBatchDelete"
          :loading="batchDeleting"
        >
          <el-icon><Delete /></el-icon>
          批量删除
        </el-button>
      </div>
    </div>

    <!-- 文件列表 -->
    <div class="file-list-content" v-loading="loading || false">
      <el-empty
        v-if="!loading && files.length === 0"
        description="暂无文件"
        :image-size="100"
      />
      <!-- 网格视图 -->
      <div v-else-if="viewMode === 'grid'" class="file-grid">
        <div
          v-for="file in files"
          :key="file.id"
          class="file-card"
          :class="[getFileTypeClass(file), { 'file-selected': isSelected(file) }]"
          @click="handleFileClick(file)"
        >
          <div class="file-checkbox" @click.stop>
            <el-checkbox
              :model-value="isSelected(file)"
              @change="toggleSelection(file)"
            />
          </div>
          <div class="file-card-header">
            <div class="file-icon-wrapper">
              <div class="file-icon-bg"></div>
              <el-icon v-if="getFileIcon(file)" :size="40" class="file-icon">
                <component :is="getFileIcon(file)" />
              </el-icon>
              <span v-else class="file-extension">{{ getFileExtension(file.filename) }}</span>
              <div class="file-type-badge">{{ getFileTypeLabel(file) }}</div>
            </div>
            <div class="file-actions" @click.stop>
              <el-dropdown trigger="click" @command="(cmd) => handleAction(cmd, file)" placement="bottom-end">
                <el-button text circle class="action-btn" title="更多操作">
                  <el-icon :size="18"><MoreFilled /></el-icon>
                </el-button>
                <template #dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item command="preview">
                      <el-icon><View /></el-icon>
                      预览
                    </el-dropdown-item>
                    <el-dropdown-item
                      v-if="isEditableFile(file)"
                      command="edit"
                    >
                      <el-icon><Edit /></el-icon>
                      编辑
                    </el-dropdown-item>
                    <el-dropdown-item command="share">
                      <el-icon><Share /></el-icon>
                      分享
                    </el-dropdown-item>
                    <el-dropdown-item command="download">
                      <el-icon><Download /></el-icon>
                      下载
                    </el-dropdown-item>
                    <el-dropdown-item command="move" divided>
                      <el-icon><FolderOpened /></el-icon>
                      移动到
                    </el-dropdown-item>
                    <el-dropdown-item command="delete" divided>
                      <el-icon><Delete /></el-icon>
                      删除
                    </el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </div>
          </div>
          <div class="file-card-body">
            <div class="file-info">
              <div class="file-title" :title="file.title">{{ file.title }}</div>
              <div class="file-meta">
                <span class="file-size">
                  <el-icon><Document /></el-icon>
                  {{ formatFileSize(file.file_size) }}
                </span>
                <span class="file-date">
                  <el-icon><Clock /></el-icon>
                  {{ formatDate(file.created_at) }}
                </span>
              </div>
              <div class="file-tags" v-if="file.tags && file.tags.length > 0">
                <el-tag
                  v-for="tag in file.tags.slice(0, 2)"
                  :key="tag"
                  size="small"
                  effect="plain"
                  class="file-tag"
                >
                  {{ tag }}
                </el-tag>
                <el-tag v-if="file.tags.length > 2" size="small" effect="plain" type="info">
                  +{{ file.tags.length - 2 }}
                </el-tag>
              </div>
            </div>
          </div>
        </div>
      </div>
      <!-- 列表视图 -->
      <div v-else class="file-list">
        <div
          v-for="file in files"
          :key="file.id"
          class="file-list-item"
          :class="[getFileTypeClass(file), { 'file-selected': isSelected(file) }]"
          @click="handleFileClick(file)"
        >
          <div class="list-item-checkbox" @click.stop>
            <el-checkbox
              :model-value="isSelected(file)"
              @change="toggleSelection(file)"
            />
          </div>
          <div class="list-item-icon">
            <div class="icon-wrapper">
              <el-icon v-if="getFileIcon(file)" :size="32" class="file-icon">
                <component :is="getFileIcon(file)" />
              </el-icon>
              <span v-else class="file-extension">{{ getFileExtension(file.filename) }}</span>
            </div>
          </div>
          <div class="list-item-content">
            <div class="list-item-title" :title="file.title">{{ file.title }}</div>
            <div class="list-item-meta">
              <span class="meta-item">
                <el-icon><Document /></el-icon>
                {{ formatFileSize(file.file_size) }}
              </span>
              <span class="meta-item">
                <el-icon><Clock /></el-icon>
                {{ formatDate(file.created_at) }}
              </span>
              <el-tag
                v-if="getFileTypeLabel(file)"
                size="small"
                effect="plain"
                class="type-tag"
              >
                {{ getFileTypeLabel(file) }}
              </el-tag>
            </div>
            <div class="list-item-tags" v-if="file.tags && file.tags.length > 0">
              <el-tag
                v-for="tag in file.tags.slice(0, 3)"
                :key="tag"
                size="small"
                effect="plain"
                class="file-tag"
              >
                {{ tag }}
              </el-tag>
            </div>
          </div>
          <div class="list-item-actions" @click.stop>
            <el-dropdown trigger="click" @command="(cmd) => handleAction(cmd, file)">
              <el-button text circle size="small" class="action-btn">
                <el-icon><MoreFilled /></el-icon>
              </el-button>
              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item command="preview">
                    <el-icon><View /></el-icon>
                    预览
                  </el-dropdown-item>
                  <el-dropdown-item
                    v-if="isEditableFile(file)"
                    command="edit"
                  >
                    <el-icon><Edit /></el-icon>
                    编辑
                  </el-dropdown-item>
                  <el-dropdown-item command="share">
                    <el-icon><Share /></el-icon>
                    分享
                  </el-dropdown-item>
                  <el-dropdown-item command="download">
                    <el-icon><Download /></el-icon>
                    下载
                  </el-dropdown-item>
                  <el-dropdown-item command="move" divided>
                    <el-icon><FolderOpened /></el-icon>
                    移动到
                  </el-dropdown-item>
                  <el-dropdown-item command="delete" divided>
                    <el-icon><Delete /></el-icon>
                    删除
                  </el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
          </div>
        </div>
      </div>
    </div>

    <!-- 分页 -->
    <div class="pagination" v-if="pagination.total > 0">
      <el-pagination
        v-model:current-page="pagination.page"
        v-model:page-size="pagination.size"
        :total="pagination.total"
        :page-sizes="[10, 20, 50, 100]"
        layout="total, sizes, prev, pager, next, jumper"
        @size-change="handlePageSizeChange"
        @current-change="handlePageChange"
      />
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  Document,
  Picture,
  VideoPlay,
  Headset,
  Search,
  MoreFilled,
  View,
  Edit,
  Share,
  Download,
  Delete,
  FolderOpened,
  Clock,
  Grid,
  List,
  Select
} from '@element-plus/icons-vue'
import type { KnowledgeFile } from '@/api/knowledge'
import { formatFileSize } from '@/utils/common'
import { formatDate } from '@/utils/date'
import { batchDeleteKnowledgeFiles } from '@/api/knowledge'
import { ResponseParser } from '@/utils/responseParser'

interface Props {
  files: KnowledgeFile[]
  loading?: boolean
  pagination: {
    page: number
    size: number
    total: number
  }
}

interface Emits {
  (e: 'file-click', file: KnowledgeFile): void
  (e: 'preview', file: KnowledgeFile): void
  (e: 'edit', file: KnowledgeFile): void
  (e: 'share', file: KnowledgeFile): void
  (e: 'download', file: KnowledgeFile): void
  (e: 'delete', file: KnowledgeFile): void
  (e: 'move', file: KnowledgeFile): void
  (e: 'search', keyword: string): void
  (e: 'filter-change', fileType: string): void
  (e: 'page-change', page: number): void
  (e: 'page-size-change', size: number): void
  (e: 'batch-deleted', fileIds: string[]): void
}

defineProps<Props>()
const emit = defineEmits<Emits>()

const searchKeyword = ref('')
const fileTypeFilter = ref('')
const viewMode = ref<'grid' | 'list'>('grid')
const selectedFiles = ref<KnowledgeFile[]>([])
const batchDeleting = ref(false)

// 获取文件图标
const getFileIcon = (file: KnowledgeFile) => {
  const format = file.format?.toLowerCase()
  const fileType = file.file_type

  if (fileType === 'image') return Picture
  if (fileType === 'video') return VideoPlay
  if (fileType === 'audio') return Headset
  if (['pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'].includes(format || '')) {
    return Document
  }
  return null
}

// 获取文件扩展名
const getFileExtension = (filename: string) => {
  const lastDot = filename.lastIndexOf('.')
  if (lastDot > 0) {
    return filename.substring(lastDot + 1).toUpperCase()
  }
  return 'FILE'
}

// 获取文件类型样式类
const getFileTypeClass = (file: KnowledgeFile) => {
  const fileType = file.file_type
  if (fileType === 'image') return 'file-type-image'
  if (fileType === 'video') return 'file-type-video'
  if (fileType === 'audio') return 'file-type-audio'
  if (fileType === 'document') return 'file-type-document'
  return 'file-type-other'
}

// 获取文件类型标签
const getFileTypeLabel = (file: KnowledgeFile) => {
  const fileType = file.file_type
  const typeMap: Record<string, string> = {
    image: '图片',
    video: '视频',
    audio: '音频',
    document: '文档',
    other: '其他'
  }
  return typeMap[fileType] || '文件'
}

// 判断是否可编辑文件
const isEditableFile = (file: KnowledgeFile) => {
  const editableFormats = ['txt', 'md', 'html', 'json', 'xml', 'csv']
  return editableFormats.includes(file.format?.toLowerCase() || '')
}

// 文件点击
const handleFileClick = (file: KnowledgeFile) => {
  emit('file-click', file)
}

// 操作处理
const handleAction = (command: string, file: KnowledgeFile) => {
  switch (command) {
    case 'preview':
      emit('preview', file)
      break
    case 'edit':
      emit('edit', file)
      break
    case 'share':
      emit('share', file)
      break
    case 'download':
      emit('download', file)
      break
    case 'move':
      emit('move', file)
      break
    case 'delete':
      handleDelete(file)
      break
  }
}

// 删除文件
const handleDelete = async (file: KnowledgeFile) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除文件 "${file.title}" 吗？此操作不可恢复。`,
      '删除文件',
      { type: 'warning' }
    )
    emit('delete', file)
    // 如果文件在选中列表中，移除它
    const index = selectedFiles.value.findIndex(f => f.id === file.id)
    if (index > -1) {
      selectedFiles.value.splice(index, 1)
    }
  } catch (error) {
    // 用户取消
  }
}

// 搜索
const handleSearch = () => {
  emit('search', searchKeyword.value)
}

// 筛选变化
const handleFilterChange = () => {
  emit('filter-change', fileTypeFilter.value)
}

// 分页变化
const handlePageChange = (page: number) => {
  emit('page-change', page)
}

const handlePageSizeChange = (size: number) => {
  emit('page-size-change', size)
}

// 批量选择相关
const isSelected = (file: KnowledgeFile) => {
  return selectedFiles.value.some(f => f.id === file.id)
}

const toggleSelection = (file: KnowledgeFile) => {
  const index = selectedFiles.value.findIndex(f => f.id === file.id)
  if (index > -1) {
    selectedFiles.value.splice(index, 1)
  } else {
    selectedFiles.value.push(file)
  }
}

const clearSelection = () => {
  selectedFiles.value = []
}

// 批量删除
const handleBatchDelete = async () => {
  if (selectedFiles.value.length === 0) {
    ElMessage.warning('请选择要删除的文件')
    return
  }

  try {
    await ElMessageBox.confirm(
      `确定要删除选中的 ${selectedFiles.value.length} 个文件吗？此操作不可恢复。`,
      '批量删除文件',
      {
        type: 'warning',
        confirmButtonText: '确定删除',
        cancelButtonText: '取消'
      }
    )

    batchDeleting.value = true
    const fileIds = selectedFiles.value.map(f => f.id)
    
    const response = await batchDeleteKnowledgeFiles(fileIds)
    const parsed = ResponseParser.parseResponse<{
      success_count: number
      fail_count: number
      errors?: string[]
    }>(response)

    if (parsed.success) {
      const { success_count, fail_count } = parsed.data || {}
      if (fail_count === 0) {
        ElMessage.success(`成功删除 ${success_count} 个文件`)
      } else {
        ElMessage.warning(`成功删除 ${success_count} 个文件，${fail_count} 个文件删除失败`)
      }
      
      clearSelection()
      emit('batch-deleted', fileIds)
    } else {
      ElMessage.error(parsed.message || '批量删除失败')
    }
  } catch (error: any) {
    if (error !== 'cancel') {
      console.error('批量删除失败:', error)
      ElMessage.error('批量删除失败，请稍后重试')
    }
  } finally {
    batchDeleting.value = false
  }
}
</script>

<style scoped lang="scss">
.knowledge-file-list {
  height: 100%;
  display: flex;
  flex-direction: column;

  .batch-actions-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 20px;
    background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
    border-bottom: 1px solid #fbbf24;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);

    .batch-info {
      display: flex;
      align-items: center;
      gap: 8px;
      color: #92400e;
      font-size: 14px;

      .el-icon {
        font-size: 18px;
      }

      strong {
        color: #78350f;
        font-weight: 600;
      }
    }

    .batch-buttons {
      display: flex;
      gap: 8px;
    }
  }

  .search-bar {
    display: flex;
    gap: 12px;
    align-items: center;
    padding: 16px 20px;
    border-bottom: 1px solid #e2e8f0;
    background: linear-gradient(to bottom, #ffffff 0%, #f8fafc 100%);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);

    .search-input {
      flex: 1;
      max-width: 400px;

      :deep(.el-input__wrapper) {
        border-radius: 10px;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
        transition: all 0.3s;

        &:hover {
          box-shadow: 0 4px 8px rgba(0, 0, 0, 0.08);
        }

        &.is-focus {
          box-shadow: 0 0 0 2px rgba(6, 182, 212, 0.2);
        }
      }
    }

    .view-toggle {
      margin-left: auto;

      .view-mode-switcher {
        :deep(.el-radio-button__inner) {
          display: flex;
          align-items: center;
          gap: 6px;
          padding: 8px 16px;
          border-radius: 8px;
          transition: all 0.3s;

          .el-icon {
            font-size: 16px;
          }

          .view-label {
            font-size: 13px;
          }
        }

        :deep(.el-radio-button__original-radio:checked + .el-radio-button__inner) {
          background: linear-gradient(135deg, #06b6d4 0%, #3b82f6 100%);
          border-color: transparent;
          color: #fff;
          box-shadow: 0 2px 8px rgba(6, 182, 212, 0.3);
        }
      }
    }
  }

  .file-list-content {
    flex: 1;
    overflow-y: auto;
    padding: 16px;

    .file-grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
      gap: 20px;
      
      @media (max-width: 768px) {
        grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
        gap: 12px;
      }
      
      @media (min-width: 1400px) {
        grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
      }

      .file-card {
        position: relative;
        background: #fff;
        border: 1px solid #e2e8f0;
        border-radius: 12px;
        overflow: hidden;
        cursor: pointer;
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        display: flex;
        flex-direction: column;
        height: 100%;

        &:hover {
          transform: translateY(-4px);
          box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
          border-color: transparent;

          .file-card-header {
            .file-icon-wrapper {
              transform: scale(1.05);
              
              .file-icon-bg {
                opacity: 1;
              }
            }
          }

          .file-actions {
            opacity: 1;
            transform: translateY(0) scale(1);
          }
        }

        &:active {
          transform: translateY(-2px);
          transition: transform 0.1s;
        }

        &.file-selected {
          border: 2px solid #06b6d4;
          box-shadow: 0 0 0 3px rgba(6, 182, 212, 0.1);
        }

        .file-checkbox {
          position: absolute;
          top: 12px;
          left: 12px;
          z-index: 10;
          background: rgba(255, 255, 255, 0.95);
          backdrop-filter: blur(10px);
          border-radius: 6px;
          padding: 4px;
          box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
        }

        // 图片类型样式
        &.file-type-image {
          .file-card-header {
            background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
          }
          .file-icon {
            color: #f59e0b;
          }
          .file-icon-bg {
            background: rgba(245, 158, 11, 0.1);
          }
          &:hover {
            box-shadow: 0 8px 24px rgba(245, 158, 11, 0.2);
          }
        }

        // 视频类型样式
        &.file-type-video {
          .file-card-header {
            background: linear-gradient(135deg, #ddd6fe 0%, #c4b5fd 100%);
          }
          .file-icon {
            color: #8b5cf6;
          }
          .file-icon-bg {
            background: rgba(139, 92, 246, 0.1);
          }
          &:hover {
            box-shadow: 0 8px 24px rgba(139, 92, 246, 0.2);
          }
        }

        // 音频类型样式
        &.file-type-audio {
          .file-card-header {
            background: linear-gradient(135deg, #fce7f3 0%, #fbcfe8 100%);
          }
          .file-icon {
            color: #ec4899;
          }
          .file-icon-bg {
            background: rgba(236, 72, 153, 0.1);
          }
          &:hover {
            box-shadow: 0 8px 24px rgba(236, 72, 153, 0.2);
          }
        }

        // 文档类型样式
        &.file-type-document {
          .file-card-header {
            background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);
          }
          .file-icon {
            color: #3b82f6;
          }
          .file-icon-bg {
            background: rgba(59, 130, 246, 0.1);
          }
          &:hover {
            box-shadow: 0 8px 24px rgba(59, 130, 246, 0.2);
          }
        }

        // 其他类型样式
        &.file-type-other {
          .file-card-header {
            background: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%);
          }
          .file-icon {
            color: #64748b;
          }
          .file-icon-bg {
            background: rgba(100, 116, 139, 0.1);
          }
          &:hover {
            box-shadow: 0 8px 24px rgba(100, 116, 139, 0.15);
          }
        }

        .file-card-header {
          position: relative;
          padding: 20px;
          min-height: 120px;
          display: flex;
          align-items: center;
          justify-content: center;
          transition: all 0.3s;

          .file-icon-wrapper {
            position: relative;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            width: 100%;
            transition: transform 0.3s;

            .file-icon-bg {
              position: absolute;
              top: 50%;
              left: 50%;
              transform: translate(-50%, -50%);
              width: 80px;
              height: 80px;
              border-radius: 16px;
              opacity: 0;
              transition: opacity 0.3s;
            }

            .file-icon {
              position: relative;
              z-index: 1;
              margin-bottom: 8px;
            }

            .file-extension {
              position: relative;
              z-index: 1;
              font-size: 16px;
              font-weight: 700;
              color: inherit;
              margin-bottom: 8px;
            }

            .file-type-badge {
              position: relative;
              z-index: 1;
              font-size: 11px;
              font-weight: 600;
              padding: 2px 8px;
              border-radius: 12px;
              background: rgba(255, 255, 255, 0.9);
              backdrop-filter: blur(10px);
              color: inherit;
              box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
            }
          }

          .file-actions {
            position: absolute;
            top: 12px;
            right: 12px;
            opacity: 0.9;
            transform: translateY(0) scale(1);
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            z-index: 10;
            pointer-events: auto;

            .action-btn {
              width: 40px;
              height: 40px;
              min-width: 40px;
              background: linear-gradient(135deg, rgba(255, 255, 255, 0.98) 0%, rgba(255, 255, 255, 0.95) 100%);
              backdrop-filter: blur(16px);
              box-shadow: 
                0 4px 16px rgba(0, 0, 0, 0.12),
                0 0 0 1.5px rgba(255, 255, 255, 0.8),
                inset 0 1px 2px rgba(255, 255, 255, 0.9);
              border: 1.5px solid rgba(255, 255, 255, 0.9);
              color: #1e293b;
              transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
              display: flex;
              align-items: center;
              justify-content: center;
              
              &::before {
                content: '';
                position: absolute;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                width: 6px;
                height: 6px;
                background: currentColor;
                border-radius: 50%;
                opacity: 0.3;
                transition: all 0.3s;
              }
              
              .el-icon {
                position: relative;
                z-index: 1;
                font-size: 20px;
                font-weight: 600;
                color: #1e293b;
                transition: all 0.3s;
              }
              
              &:hover {
                opacity: 1;
                background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
                transform: scale(1.15) rotate(90deg);
                box-shadow: 
                  0 8px 24px rgba(6, 182, 212, 0.25),
                  0 0 0 3px rgba(6, 182, 212, 0.15),
                  inset 0 1px 3px rgba(255, 255, 255, 1);
                border-color: #06b6d4;
                
                &::before {
                  opacity: 0.6;
                  transform: translate(-50%, -50%) scale(1.5);
                  background: #06b6d4;
                }
                
                .el-icon {
                  color: #06b6d4;
                  transform: scale(1.1);
                }
              }

              &:active {
                transform: scale(1.05) rotate(90deg);
              }
            }
          }
        }

        .file-card-body {
          padding: 16px;
          flex: 1;
          display: flex;
          flex-direction: column;

          .file-info {
            flex: 1;

            .file-title {
              font-size: 14px;
              font-weight: 600;
              color: #1e293b;
              margin-bottom: 12px;
              overflow: hidden;
              text-overflow: ellipsis;
              display: -webkit-box;
              -webkit-line-clamp: 2;
              -webkit-box-orient: vertical;
              line-height: 1.5;
              min-height: 42px;
            }

            .file-meta {
              display: flex;
              flex-direction: column;
              gap: 6px;
              font-size: 12px;
              color: #64748b;
              margin-bottom: 12px;

              .file-size,
              .file-date {
                display: flex;
                align-items: center;
                gap: 4px;

                .el-icon {
                  font-size: 14px;
                }
              }
            }

            .file-tags {
              display: flex;
              gap: 6px;
              flex-wrap: wrap;

              .file-tag {
                border-radius: 6px;
                font-size: 11px;
              }
            }
          }
        }
      }
    }

    // 列表视图样式
    .file-list {
      display: flex;
      flex-direction: column;
      gap: 8px;

      .file-list-item {
        display: flex;
        align-items: center;
        gap: 16px;
        padding: 16px 20px;
        background: #fff;
        border: 1px solid #e2e8f0;
        border-radius: 12px;
        cursor: pointer;
        transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        position: relative;

        &:hover {
          border-color: transparent;
          box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
          transform: translateX(4px);

          .list-item-actions {
            opacity: 1;
          }
        }

        &:active {
          transform: translateX(2px);
        }

        // 图片类型样式
        &.file-type-image {
          border-left: 4px solid #f59e0b;
          
          &:hover {
            box-shadow: 0 4px 12px rgba(245, 158, 11, 0.15);
          }
        }

        // 视频类型样式
        &.file-type-video {
          border-left: 4px solid #8b5cf6;
          
          &:hover {
            box-shadow: 0 4px 12px rgba(139, 92, 246, 0.15);
          }
        }

        // 音频类型样式
        &.file-type-audio {
          border-left: 4px solid #ec4899;
          
          &:hover {
            box-shadow: 0 4px 12px rgba(236, 72, 153, 0.15);
          }
        }

        // 文档类型样式
        &.file-type-document {
          border-left: 4px solid #3b82f6;
          
          &:hover {
            box-shadow: 0 4px 12px rgba(59, 130, 246, 0.15);
          }
        }

        // 其他类型样式
        &.file-type-other {
          border-left: 4px solid #64748b;
          
          &:hover {
            box-shadow: 0 4px 12px rgba(100, 116, 139, 0.1);
          }
        }

        &.file-selected {
          border-left-width: 6px;
          background: linear-gradient(to right, rgba(6, 182, 212, 0.05) 0%, transparent 100%);
        }

        .list-item-checkbox {
          flex-shrink: 0;
          margin-right: 12px;
        }

        .list-item-icon {
          flex-shrink: 0;
          width: 56px;
          height: 56px;
          display: flex;
          align-items: center;
          justify-content: center;

          .icon-wrapper {
            width: 100%;
            height: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 12px;
            background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
            transition: all 0.3s;

            .file-icon {
              color: inherit;
            }

            .file-extension {
              font-size: 12px;
              font-weight: 700;
              color: #64748b;
            }
          }
        }

        // 图片类型图标背景
        &.file-type-image .icon-wrapper {
          background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
          .file-icon { color: #f59e0b; }
        }

        // 视频类型图标背景
        &.file-type-video .icon-wrapper {
          background: linear-gradient(135deg, #ddd6fe 0%, #c4b5fd 100%);
          .file-icon { color: #8b5cf6; }
        }

        // 音频类型图标背景
        &.file-type-audio .icon-wrapper {
          background: linear-gradient(135deg, #fce7f3 0%, #fbcfe8 100%);
          .file-icon { color: #ec4899; }
        }

        // 文档类型图标背景
        &.file-type-document .icon-wrapper {
          background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);
          .file-icon { color: #3b82f6; }
        }

        .list-item-content {
          flex: 1;
          min-width: 0;
          display: flex;
          flex-direction: column;
          gap: 8px;

          .list-item-title {
            font-size: 15px;
            font-weight: 600;
            color: #1e293b;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
          }

          .list-item-meta {
            display: flex;
            align-items: center;
            gap: 16px;
            font-size: 13px;
            color: #64748b;

            .meta-item {
              display: flex;
              align-items: center;
              gap: 4px;

              .el-icon {
                font-size: 14px;
              }
            }

            .type-tag {
              border-radius: 6px;
              font-size: 11px;
            }
          }

          .list-item-tags {
            display: flex;
            gap: 6px;
            flex-wrap: wrap;

            .file-tag {
              border-radius: 6px;
              font-size: 11px;
            }
          }
        }

        .list-item-actions {
          flex-shrink: 0;
          opacity: 0;
          transition: opacity 0.3s;

          .action-btn {
            background: rgba(255, 255, 255, 0.9);
            backdrop-filter: blur(10px);
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
            
            &:hover {
              background: rgba(255, 255, 255, 1);
              transform: scale(1.1);
            }
          }
        }
      }
    }
  }

  .pagination {
    padding: 16px;
    border-top: 1px solid var(--el-border-color);
    background: #fff;
    display: flex;
    justify-content: flex-end;
  }
}
</style>

